//
//  DWHTTPManager.m
//  GMNBase
//
//  Created by DarkWorld on 2019/11/28.
//  Copyright © 2019 Mengnan Gong. All rights reserved.
//

#import "DWHTTPManager.h"
#import "DWHttpClient.h"

//DEBUG  release

static NSMutableArray *_allSessionTask;


@implementation DWHTTPManager

+ (void)monitoringNetworkState:(void (^)(MYNetWorkStatus))block{
    
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    [manager startMonitoring];
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        switch (status) {
            case AFNetworkReachabilityStatusUnknown:
            {
                //未知网络
                DLog(@"[网络状态切换]--未知网络");
            }
                break;
            case AFNetworkReachabilityStatusNotReachable:
            {
                //无法联网
                DLog(@"[网络状态切换]--无法联网");
            }
                break;
                
            case AFNetworkReachabilityStatusReachableViaWWAN:
            {
                //手机自带网络
                DLog(@"[网络状态切换]--当前使用的是2g/3g/4g网络");
            }
                break;
            case AFNetworkReachabilityStatusReachableViaWiFi:
            {
                //WIFI
                DLog(@"[网络状态切换]--当前在WIFI网络下");
            }
                
        }
        block(status);
    }];
}
#pragma mark 普通一般的网络请求
/**
 封装AFN 请求  请求使用jsonbody

 @param urlString 请求链接
 @param parameters 请求参数
 @param requestType 请求类型 get post
 @param MYServiceModuleType 服务模块类型
 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)postJsonAFNWithUrl:(NSString *)urlString
               parameters:(id)parameters
              requestType:(NSString *)requestType
   MYServiceModuleType:(MYServiceModuleType)MYServiceModuleType
         successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
         failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
    DWHttpClient *httpClinet;
    switch (MYServiceModuleType) {
       
        case MYServiceModule_Member:
            httpClinet = [DWHttpClient sharedMemberManager];
            break;
        case MYServiceModule_social:
            httpClinet = [DWHttpClient sharedSocialManager];
            break;
        case MYServiceModule_kafka_consumer:
            httpClinet = [DWHttpClient sharedKafka_consumerManager];
            break;
        case MYServiceModule_payment:
            httpClinet = [DWHttpClient sharedPaymentManager];
            break;
        case MYServiceModule_seller:
            httpClinet = [DWHttpClient sharedSellerManager];
            break;
        case MYServiceModule_shop:
            httpClinet = [DWHttpClient sharedShopManager];
            break;
        case MYServiceModule_goods:
            httpClinet = [DWHttpClient sharedGoodsManager];
            break;
        case MYServiceModule_order:
            httpClinet = [DWHttpClient sharedOrderManager];
            break;
        case MYServiceModule_tool:
            httpClinet = [DWHttpClient sharedToolManager];
            break;
        case MYServiceModule_normal:
            httpClinet = [DWHttpClient sharedNoBaseUrlManager];
            break;
        case MYServiceModule_live:
            httpClinet = [DWHttpClient sharedLiveManager];
            break;
        case MYServiceModule_AliVideo:
            httpClinet = [DWHttpClient sharedAliVideoManager];
            break;
        case MYServiceModule_VideoV3:
            httpClinet = [DWHttpClient sharedVideoV3Manager];
            break;
        
    }
   
    [httpClinet.requestSerializer setValue:@"application/json;" forHTTPHeaderField:@"Content-Type"];

    NSString *allUrl = [NSString stringWithFormat:@"%@%@",httpClinet.baseURL.absoluteString, urlString];
    DLog(@"\nurl:%@\nparam:%@",allUrl,parameters);

    NSString* encodedRequestUrl = [allUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];//转码
    
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:encodedRequestUrl] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPMethod:requestType];
   
    
    
    NSData *body = [parameters dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBody = body;
    NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager* manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    NSURLSessionDataTask* task = [manager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        
        if (responseObject)
        {
            NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];
            
            successHandle(task,dict);
            
            NSLog(@"----%@",dict);

        }
        else
        {
            failureHandle(task,error);
            dispatch_async(dispatch_get_main_queue(), ^{
                if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
                {
                    [SVProgressHUD dismiss];

                    if(error.code != NSURLErrorTimedOut)
                    {
                        if ([self checkError:error])
                        {
                            [MYTipUtils showAlertString:error.localizedDescription];
                        }
                    }
                }
                else
                {
                    [SVProgressHUD dismiss];
                }
            });

        }
    }];
    [task resume];
}

/**
 封装AFN POST请求
 
 @param urlString 请求链接
 @param parameters 请求参数
 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)postAFNWithUrl:(NSString *)urlString
            parameters:(id)parameters
MYServiceModuleType:(MYServiceModuleType)MYServiceModuleType
         successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
         failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
    DWHttpClient *httpClinet;
    switch (MYServiceModuleType) {
       
        case MYServiceModule_Member:
            httpClinet = [DWHttpClient sharedMemberManager];
            break;
        case MYServiceModule_social:
            httpClinet = [DWHttpClient sharedSocialManager];
            break;
        case MYServiceModule_kafka_consumer:
            httpClinet = [DWHttpClient sharedKafka_consumerManager];
            break;
        case MYServiceModule_payment:
            httpClinet = [DWHttpClient sharedPaymentManager];
            break;
        case MYServiceModule_seller:
            httpClinet = [DWHttpClient sharedSellerManager];
            break;
        case MYServiceModule_shop:
            httpClinet = [DWHttpClient sharedShopManager];
            break;
        case MYServiceModule_goods:
            httpClinet = [DWHttpClient sharedGoodsManager];
            break;
        case MYServiceModule_order:
            httpClinet = [DWHttpClient sharedOrderManager];
            break;
        case MYServiceModule_tool:
            httpClinet = [DWHttpClient sharedToolManager];
            break;
        case MYServiceModule_normal:
            httpClinet = [DWHttpClient sharedNoBaseUrlManager];
            break;
        case MYServiceModule_live:
            httpClinet = [DWHttpClient sharedLiveManager];
            break;
        case MYServiceModule_AliVideo:
            httpClinet = [DWHttpClient sharedAliVideoManager];
            break;
        case MYServiceModule_VideoV3:
            httpClinet = [DWHttpClient sharedVideoV3Manager];
            break;
        
    }
   
    if (MYServiceModuleType != MYServiceModule_AliVideo) {
        [self setAuthorization:httpClinet withUrlStr:urlString];
    }

    
    [httpClinet.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    DLog(@"\nurl:%@%@\nparam:%@",httpClinet.baseURL.absoluteString, urlString,parameters);
    
    NSURLSessionDataTask *sessionTask = [httpClinet POST:urlString parameters:parameters  progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];
//
        successHandle(task,dict);
        [[self allSessionTask] removeObject:task];

        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        failureHandle(task,error);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
            {
                [SVProgressHUD dismiss];

                if(error.code != NSURLErrorTimedOut)
                {
                    if ([self checkError:error])
                    {
                        [MYTipUtils showAlertString:error.localizedDescription];
                    }
                }
            }
            else
            {
                [SVProgressHUD dismiss];
            }
        });

        [[self allSessionTask] removeObject:task];

    }];
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
}

/**
 封装AFN GET请求
 
 @param urlString 请求链接
 @param parameters 请求参数
 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)getAFNWithUrl:(NSString *)urlString
           parameters:(id)parameters
MYServiceModuleType:(MYServiceModuleType)MYServiceModuleType
        successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
        failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
   
    
    DWHttpClient *httpClinet;
    switch (MYServiceModuleType) {
       
        case MYServiceModule_Member:
            httpClinet = [DWHttpClient sharedMemberManager];
            break;
        case MYServiceModule_social:
            httpClinet = [DWHttpClient sharedSocialManager];
            break;
        case MYServiceModule_kafka_consumer:
            httpClinet = [DWHttpClient sharedKafka_consumerManager];
            break;
        case MYServiceModule_payment:
            httpClinet = [DWHttpClient sharedPaymentManager];
            break;
        case MYServiceModule_seller:
            httpClinet = [DWHttpClient sharedSellerManager];
            break;
        case MYServiceModule_shop:
            httpClinet = [DWHttpClient sharedShopManager];
            break;
        case MYServiceModule_goods:
            httpClinet = [DWHttpClient sharedGoodsManager];
            break;
        case MYServiceModule_order:
            httpClinet = [DWHttpClient sharedOrderManager];
            break;
        case MYServiceModule_tool:
            httpClinet = [DWHttpClient sharedToolManager];
            break;
        case MYServiceModule_normal:
            httpClinet = [DWHttpClient sharedNoBaseUrlManager];
            break;
        case MYServiceModule_live:
            httpClinet = [DWHttpClient sharedLiveManager];
            break;

        case MYServiceModule_AliVideo:
            httpClinet = [DWHttpClient sharedAliVideoManager];
            break;
        case MYServiceModule_VideoV3:
            httpClinet = [DWHttpClient sharedVideoV3Manager];
            break;
    }
    if (MYServiceModuleType != MYServiceModule_AliVideo) {
        [self setAuthorization:httpClinet withUrlStr:urlString];
    }

    //响应对象
   
    [httpClinet.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    
    DLog(@"\nurl:%@%@\nparam:%@",httpClinet.baseURL.absoluteString, urlString,parameters);
    NSURLSessionDataTask *sessionTask = [httpClinet GET:urlString parameters:parameters  progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];
        successHandle(task,dict);
        [[self allSessionTask] removeObject:task];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failureHandle(task,error);

        dispatch_async(dispatch_get_main_queue(), ^{
            if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
            {
                [SVProgressHUD dismiss];

                if(error.code != NSURLErrorTimedOut)
                {
                    if ([self checkError:error])
                    {
                        [MYTipUtils showAlertString:error.localizedDescription];
                    }
                }
            }
            else
            {
                [SVProgressHUD dismiss];
            }
        });
        [[self allSessionTask] removeObject:task];

    }];
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
}
/**
 封装AFN DELETE请求
 
 @param urlString 请求链接
 @param parameters 请求参数
 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)deleteAFNWithUrl:(NSString *)urlString
            parameters:(id)parameters
MYServiceModuleType:(MYServiceModuleType)MYServiceModuleType
         successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
         failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
    DWHttpClient *httpClinet;
    switch (MYServiceModuleType) {
       
        case MYServiceModule_Member:
            httpClinet = [DWHttpClient sharedMemberManager];
            break;
        case MYServiceModule_social:
            httpClinet = [DWHttpClient sharedSocialManager];
            break;
        case MYServiceModule_kafka_consumer:
            httpClinet = [DWHttpClient sharedKafka_consumerManager];
            break;
        case MYServiceModule_payment:
            httpClinet = [DWHttpClient sharedPaymentManager];
            break;
        case MYServiceModule_seller:
            httpClinet = [DWHttpClient sharedSellerManager];
            break;
        case MYServiceModule_shop:
            httpClinet = [DWHttpClient sharedShopManager];
            break;
        case MYServiceModule_goods:
            httpClinet = [DWHttpClient sharedGoodsManager];
            break;
        case MYServiceModule_order:
            httpClinet = [DWHttpClient sharedOrderManager];
            break;
        case MYServiceModule_tool:
            httpClinet = [DWHttpClient sharedToolManager];
            break;
        case MYServiceModule_live:
            httpClinet = [DWHttpClient sharedLiveManager];
            break;
        case MYServiceModule_normal:
        httpClinet = [DWHttpClient sharedNoBaseUrlManager];
        break;
        case MYServiceModule_VideoV3:
            httpClinet = [DWHttpClient sharedVideoV3Manager];
            break;

    }
    
   [self setAuthorization:httpClinet withUrlStr:urlString];

    [httpClinet.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    
    DLog(@"\nurl:%@%@\nparam:%@",httpClinet.baseURL.absoluteString, urlString,parameters);
    NSURLSessionDataTask *sessionTask = [httpClinet DELETE:urlString parameters:parameters  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];

        successHandle(task,dict);
        [[self allSessionTask] removeObject:task];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failureHandle(task,error);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
            {
                [SVProgressHUD dismiss];

                if(error.code != NSURLErrorTimedOut)
                {
                    if ([self checkError:error])
                    {
                        [MYTipUtils showAlertString:error.localizedDescription];
                    }
                }
            }
            else
            {
                [SVProgressHUD dismiss];
            }
        });
        [[self allSessionTask] removeObject:task];

    }];
    
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
    
}
/**
 封装AFN PUT请求
 
 @param urlString 请求链接
 @param parameters 请求参数
 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)putAFNWithUrl:(NSString *)urlString
            parameters:(id)parameters
MYServiceModuleType:(MYServiceModuleType)MYServiceModuleType
         successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
         failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
    DWHttpClient *httpClinet;
    switch (MYServiceModuleType) {
       
        case MYServiceModule_Member:
            httpClinet = [DWHttpClient sharedMemberManager];
            break;
        case MYServiceModule_social:
            httpClinet = [DWHttpClient sharedSocialManager];
            break;
        case MYServiceModule_kafka_consumer:
            httpClinet = [DWHttpClient sharedKafka_consumerManager];
            break;
        case MYServiceModule_payment:
            httpClinet = [DWHttpClient sharedPaymentManager];
            break;
        case MYServiceModule_seller:
            httpClinet = [DWHttpClient sharedSellerManager];
            break;
        case MYServiceModule_shop:
            httpClinet = [DWHttpClient sharedShopManager];
            break;
        case MYServiceModule_goods:
            httpClinet = [DWHttpClient sharedGoodsManager];
            break;
        case MYServiceModule_order:
            httpClinet = [DWHttpClient sharedOrderManager];
            break;
        case MYServiceModule_tool:
            httpClinet = [DWHttpClient sharedToolManager];
            break;
        case MYServiceModule_live:
            httpClinet = [DWHttpClient sharedLiveManager];
            break;
        case MYServiceModule_normal:
        httpClinet = [DWHttpClient sharedNoBaseUrlManager];
        break;
        case MYServiceModule_AliVideo:
            httpClinet = [DWHttpClient sharedAliVideoManager];
            break;
    }
    if (MYServiceModuleType != MYServiceModule_AliVideo) {
        [self setAuthorization:httpClinet withUrlStr:urlString];
    }
   
    [httpClinet.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    
    DLog(@"\nurl:%@%@\nparam:%@",httpClinet.baseURL.absoluteString, urlString,parameters);
    NSURLSessionDataTask *sessionTask = [httpClinet PUT:urlString parameters:parameters  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];

        successHandle(task,dict);
        [[self allSessionTask] removeObject:task];

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failureHandle(task,error);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
            {
                [SVProgressHUD dismiss];

                if(error.code != NSURLErrorTimedOut)
                {
                    if ([self checkError:error])
                    {
                        [MYTipUtils showAlertString:error.localizedDescription];
                    }
                }
            }
            else
            {
                [SVProgressHUD dismiss];
            }
        });
        [[self allSessionTask] removeObject:task];

    }];
    // 添加sessionTask到数组
    sessionTask ? [[self allSessionTask] addObject:sessionTask] : nil ;
    
}
/**
 *  上传文件
 *
 *  @param urlString      url地址
 *  @param params         params参数
 *  @param mimeType         mimeType参数
 *

 @param successHandle 请求成功回调
 @param failureHandle 请求失败回调
 */
+ (void)requestDataWithURL:(NSString *)urlString
                withParams:(NSMutableDictionary *)params
                  withData:(NSData *)fileData
              withDataName:(NSString *)dataName
              withFileName:(NSString *)fileName
                  mimeType:(NSString *)mimeType
                  progress:(nullable void (^)(NSProgress * _Nonnull uploadProgress))uploadProgressZSP
             successHandle:(void(^)(NSURLSessionTask *task, id response))successHandle
             failureHandle:(void(^)(NSURLSessionTask *task, NSError *error))failureHandle
{
    if (params == nil) {
        params = [NSMutableDictionary dictionary];
    }
    
    DWHttpClient *httpClinet = [DWHttpClient sharedToolManager];
    
   [self setAuthorization:httpClinet withUrlStr:urlString];

    [httpClinet.requestSerializer setValue:@"application/x-www-form-urlencoded; charset=UTF-8;multipart/form-data" forHTTPHeaderField:@"Content-Type"];

    DLog(@"\nurl:%@%@\nparam:%@",httpClinet.baseURL.absoluteString, urlString,params);
    [httpClinet POST:urlString parameters:params   constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        [formData appendPartWithFileData:fileData name:dataName fileName:fileName mimeType:mimeType];
        

    } progress:^(NSProgress * _Nonnull uploadProgress) {
        uploadProgressZSP(uploadProgress);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
          NSDictionary *dict =  [MiaoYinTools dictionaryWithData:responseObject];
//
        successHandle(task,dict);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failureHandle(task,error);
        dispatch_async(dispatch_get_main_queue(), ^{
            if(!(error.code == NSURLErrorCancelled && [error.domain isEqualToString:NSURLErrorDomain]))
            {
                [SVProgressHUD dismiss];

                if(error.code != NSURLErrorTimedOut)
                {
                    if ([self checkError:error])
                    {
                        [MYTipUtils showAlertString:error.localizedDescription];
                    }
                }
            }
            else
            {
                [SVProgressHUD dismiss];
            }
        });

    }];
   
}

+ (NSString *)getHttpSignWithParams:(NSMutableDictionary *)params withTime:(NSString *)time
{
    NSString *sign = @"";
    
    return sign;
}

+ (void)setAuthorization:(DWHttpClient *)httpClinet withUrlStr:(NSString *)url
{

}

+ (BOOL)checkError:(NSError *)error
{
    NSDictionary * errorInfo = error.userInfo;
            if ([[errorInfo allKeys] containsObject: @"com.alamofire.serialization.response.error.data"]){
               NSData * errorData = errorInfo[@"com.alamofire.serialization.response.error.data"];
                NSDictionary * errorDict =  [NSJSONSerialization JSONObjectWithData: errorData options:NSJSONReadingAllowFragments error:nil];
               NSString * errorCodeS = errorDict[@"error"];
                if ([errorCodeS isEqualToString:@"invalid_token"]) {
                    //token失效重新登录
                    [MYTipUtils showSuccessAlertString:@"token失效请重新登录" inView:[MiaoYinTools currentVC].view duration:1.5 completion:^{
                        [MiaoYinTools logout];
                    }];


                    return NO;
                }
           }
    
    return YES;
}

/**
 存储着所有的请求task数组
 */
+ (NSMutableArray *)allSessionTask {
    if (!_allSessionTask) {
        _allSessionTask = [[NSMutableArray alloc] init];
    }
    return _allSessionTask;
}

/// 取消所有请求
+ (void)cancelAllRequest
{
    // 锁操作
    @synchronized(self) {
        [[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            [task cancel];
        }];
        [[self allSessionTask] removeAllObjects];
    }
}

/// 取消包含关键字地址的请求
/// @param URL 包含对应地址的字符串
+ (void)cancelRequestWithURL:(NSString *)URL
{
    if (!URL) { return; }
    @synchronized (self) {
        [[self allSessionTask] enumerateObjectsUsingBlock:^(NSURLSessionTask  *_Nonnull task, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([task.currentRequest.URL.absoluteString containsString:URL]) {
                [task cancel];
                [[self allSessionTask] removeObject:task];
                *stop = YES;
            }
        }];
    }
}

@end
